home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / Libraries / Aidan's Class Libraries / Source / Layout Classes / Layout.cpp < prev    next >
Encoding:
Text File  |  1997-07-19  |  10.0 KB  |  470 lines  |  [TEXT/CWIE]

  1. //Copyright (c) 1997 Aidan Cully
  2. //All rights reserved
  3.  
  4. #include "CLLayout.h"
  5. #include "CLMouseHandler.h"
  6. #include "CLBaseWindow.h"
  7.  
  8. CursPtr TLayoutLeaf::sPresCurs = 0l;
  9.  
  10. TLayoutLeaf::TLayoutLeaf( TLayoutBranch *newParent ):
  11.     mParent( newParent ),
  12.     mWindow( 0 )
  13. {
  14. }
  15.  
  16. TLayoutLeaf::~TLayoutLeaf() {
  17.     if( mParent )
  18.         mParent->RemoveChild( this );
  19. }
  20.  
  21. TLayoutBranch::TLayoutBranch( TLayoutBranch *newParent ):
  22.     TLayoutLeaf( newParent ),
  23.     mActiveChild( 0l )
  24. {
  25. }
  26.  
  27. TLayoutBranch::~TLayoutBranch() {
  28.     TChildStruct *child;
  29.     UInt32 temp;
  30.  
  31.     if( mChildren.MoveFirst() ) {
  32.         do {
  33.             mChildren.GetData( child );
  34.             child->mChild->SetParent( 0l );
  35.         } while( mChildren.MoveNext() );
  36.     }
  37. }
  38.  
  39. void TLayoutLeaf::AttachedToWindow( TBaseWindow *win, Rect contRect )
  40. {
  41.     mWindow= win;
  42.     mContentRect= contRect;
  43. }
  44.  
  45. void TLayoutBranch::AttachedToWindow( TBaseWindow *win, Rect contRect )
  46. {
  47.     TLayoutLeaf::AttachedToWindow( win, contRect );
  48.     BuildChildren();
  49. }
  50.  
  51. Boolean TLayoutLeaf::SetParent( TLayoutBranch *newParent )
  52. {
  53.     if( mParent )
  54.         mParent->RemoveChild( this );
  55.     mParent = newParent;
  56.     return( true );
  57. }
  58.  
  59. Boolean TLayoutBranch::AddChild( TLayoutLeaf *newChild, Rect contRect, Boolean *binding )
  60. {
  61.     TChildStruct *child;
  62.     bool found= false;
  63.  
  64.     if( mChildren.MoveFirst() ) {
  65.         UINT32 ch;
  66.         do {
  67.             mChildren.GetData( child );
  68.             if( child->mChild==newChild )
  69.                 found= true;
  70.         } while( (!found)&&mChildren.MoveNext() );
  71.     }
  72.     if( found ) {
  73.         for( int i= 0; i<4; i++ )
  74.             child->mBinds[i]= binding[i];
  75.         return( true );
  76.     }
  77.     mChildren.MoveLast();
  78.     child= new TChildStruct;
  79.     for( int i= 0; i<4; i++ )
  80.         child->mBinds[i]= binding[i];
  81.     child->mChild= newChild;
  82.     if( !mChildren.AddNext( child ) )
  83.         return( false );
  84.     child->mChild->AttachedToWindow( mWindow, contRect );
  85.     if( ::EmptyRect( &(newChild->GetRect()) ) )
  86.         AcceptNewSubSizeRequest( newChild->GetRect(), newChild );
  87.     return( true );
  88. }
  89.  
  90. Boolean TLayoutBranch::RemoveChild( TLayoutLeaf *deadChild )
  91. {
  92.     TChildStruct *child;
  93.     if( !mChildren.MoveFirst() )
  94.         return( true );
  95.     bool found= false;
  96.     UINT32 ch;
  97.     do {
  98.         mChildren.GetData( child );
  99.         if( child->mChild==deadChild )
  100.             found= true;
  101.     } while( !found&&mChildren.MoveNext() );
  102.     if( !found )
  103.         return( true );
  104.     mChildren.Remove();
  105.     delete child;
  106.     if( mChildren.MoveFirst() )
  107.         TrySize( mContentRect );
  108.     return( true );
  109. }
  110.  
  111. Boolean TLayoutBranch::AcceptNewSubSizeRequest( Rect newSubRect, TLayoutLeaf *sub )
  112. {
  113.     RgnHandle theRgn, subRgn;
  114.  
  115.     TChildStruct *child;
  116.     if( !mChildren.MoveFirst() )
  117.         return( false );
  118.     bool found= false;
  119.     UINT32 ch;
  120.     do {
  121.         mChildren.GetData( child );
  122.         if( child->mChild==sub )
  123.             found= true;
  124.     } while( (!found)&&mChildren.MoveNext() );
  125.     if( !found )
  126.         return( false );
  127.     theRgn = ::NewRgn();
  128.     ::RectRgn( theRgn, &mContentRect );
  129.     subRgn = ::NewRgn();
  130.     ::RectRgn( subRgn, &newSubRect );
  131.  
  132.     UInt32 temp;
  133.     mChildren.MoveFirst();
  134.     do {
  135.         mChildren.GetData( child );
  136.         if( child->mChild != sub ) {
  137.         }
  138.     } while( mChildren.MoveNext() );
  139.     ::DisposeRgn( theRgn );
  140.     ::DisposeRgn( subRgn );
  141.     return( true );
  142. }
  143.  
  144. Boolean TLayoutLeaf::Init()
  145. {
  146.     return( true );
  147. }
  148.  
  149. Boolean TLayoutLeaf::Close()
  150. {
  151.     if( mParent )
  152.         return( mParent->RemoveChild( this ) );
  153.     return( true );
  154. }
  155.  
  156. Boolean TLayoutBranch::Close()
  157. {
  158.     if( !TLayoutLeaf::Close() )
  159.         return( false );
  160.     TChildStruct *child;
  161.     UInt32 temp;
  162.     if( mChildren.MoveFirst() )
  163.         do {
  164.             mChildren.GetData( child );
  165.             child->mChild->Close();
  166.             mChildren.Remove();
  167.             delete child->mChild;
  168.             delete child;
  169.         } while( mChildren.MoveFirst() );
  170.     return( true );
  171. }
  172.  
  173. Boolean TLayoutLeaf::TrySize( Rect theSize ) {
  174.     mContentRect = theSize;
  175.     return( true );
  176. }
  177.  
  178. Boolean TLayoutBranch::TrySize( Rect theSize )
  179. {
  180.     TChildStruct *child;
  181.     UInt32 tempInt;
  182.     Rect tempRect, tRect2;
  183.     const Boolean *cBinding;
  184.  
  185.     if( mChildren.MoveFirst() ) {
  186.         do {
  187.             mChildren.GetData( child );
  188.             tempRect = child->mChild->GetRect();
  189.             tRect2 = tempRect;
  190.             cBinding = child->mBinds;
  191.             if( cBinding[right] ) {
  192.                 if( !cBinding[left] )
  193.                     OffsetRect( &tempRect, theSize.right-mContentRect.right,0 );
  194.                 else
  195.                     tempRect.right += theSize.right-mContentRect.right;
  196.             }
  197.             if( cBinding[bottom] ) {
  198.                 if( !cBinding[top] )
  199.                     OffsetRect( &tempRect, 0, theSize.bottom-mContentRect.bottom );
  200.                 else
  201.                     tempRect.bottom += theSize.bottom-mContentRect.bottom;
  202.             }
  203.             if( !EqualRect( &tempRect, &tRect2 ) )
  204.                 child->mChild->TrySize( tempRect );
  205.         } while( mChildren.MoveNext() );
  206.     }
  207.     TLayoutLeaf::TrySize( theSize );
  208. }
  209.  
  210. void TLayoutLeaf::HandleMouse( TMouseButtonEvent *ev )
  211. {
  212.     mWindow->SelectWindow();
  213.     mWindow->GlobalToLocal( &ev->where );
  214.     mWindow->GetDrawFocus();
  215.     HandleMouseSelf( ev );
  216.     mWindow->ReleaseDrawFocus();
  217. }
  218.  
  219. Boolean TLayoutLeaf::HandleMouseSelf( TMouseButtonEvent *ev )
  220. {
  221.     return( false );
  222. }
  223.  
  224. void TLayoutBranch::DrawSelf( TDrawSlate *gr )
  225. {
  226.     TChildStruct *child;
  227.     UInt32 temp;
  228.     RgnHandle outRgn, tempRgn, drawRgn, oClip;
  229.  
  230.     outRgn = ::NewRgn();
  231.     tempRgn = ::NewRgn();
  232.     drawRgn= ::NewRgn();
  233.     oClip= ::NewRgn();
  234.     ::GetClip( oClip );
  235.     if( mParent )
  236.         mParent->CalcClip( this, drawRgn );
  237.     else
  238.         ::RectRgn( drawRgn, &mContentRect );
  239.     if( mChildren.MoveFirst() )
  240.         do {
  241.             mChildren.GetData( child );
  242.             ::RectRgn( tempRgn, &child->mChild->GetRect() );
  243.             ::UnionRgn( outRgn, tempRgn, outRgn );
  244.             ::SectRgn( tempRgn, drawRgn, tempRgn );
  245.             ::SetClip( tempRgn );
  246.             child->mChild->DrawSelf( gr );
  247.             ::DiffRgn( drawRgn, tempRgn, drawRgn );
  248.         } while( mChildren.MoveNext() );
  249.     if( mParent )
  250.         mParent->CalcClip( this, drawRgn );
  251.     else
  252.         ::RectRgn( tempRgn, &mContentRect );
  253.     ::DiffRgn( tempRgn, outRgn, outRgn );
  254.     ::SetClip( tempRgn );
  255.     ::EraseRgn( outRgn );
  256.     ::DisposeRgn( outRgn );
  257.     ::DisposeRgn( tempRgn );
  258.     ::DisposeRgn( drawRgn );
  259.     ::SetClip( oClip );
  260.     ::DisposeRgn( oClip );
  261. }
  262.  
  263. void TLayoutLeaf::DrawSelf( TDrawSlate *gr )
  264. {
  265.     ::EraseRect( &GetLocalRect() );
  266. }
  267.  
  268. void TLayoutLeaf::Draw( TDrawSlate *root )
  269. {
  270.     RgnHandle oldClip, newClip;
  271.  
  272. //    ::SetOrigin( -mContentRect.left, -mContentRect.top );
  273.     newClip= ::NewRgn();
  274.     if( root->GetDrawFocus() ) {
  275.         oldClip = ::NewRgn();
  276.         ::GetClip( oldClip );
  277.         if( mParent )
  278.             mParent->CalcClip( this, newClip );
  279.         else
  280.             ::RectRgn( newClip, &GetLocalRect() );
  281.         ::SetClip( newClip );
  282.         DrawSelf( root );
  283.         ::SetClip( oldClip );
  284.         root->MarkChanged( GetRelativeRect() );
  285.         root->ReleaseDrawFocus();
  286.         ::DisposeRgn( newClip );
  287.     }
  288. //    ::SetOrigin( 0, 0 );
  289. }
  290.  
  291. Rect TLayoutBranch::GetLargestSize()
  292. {
  293.     UInt32 temp;
  294.     TChildStruct *child;
  295.     Rect retRect, tempRect;
  296.  
  297.     ::SetRect( &retRect, 0, 0, 0, 0 );
  298.     if( mChildren.MoveFirst() ) {
  299.         do {
  300.             mChildren.GetData( child );
  301.             if( child->mBinds[left] == true ) {
  302.                 tempRect = child->mChild->GetLargestSize();
  303.                 if( tempRect.right+child->mChild->GetRect().left > retRect.right )
  304.                     retRect.right = tempRect.right+child->mChild->GetRect().left;
  305.             }
  306.             if( child->mBinds[top] == true ) {
  307.                 tempRect = child->mChild->GetLargestSize();
  308.                 if( tempRect.bottom+child->mChild->GetRect().top > retRect.bottom )
  309.                     retRect.bottom = tempRect.bottom+child->mChild->GetRect().top;
  310.             }
  311.         } while( mChildren.MoveNext() );
  312.     }
  313.     return( retRect );
  314. }
  315.  
  316. Rect TLayoutLeaf::GetLocalRect()
  317. {
  318.     Rect retRect = GetRect();
  319.  
  320. //    OffsetRect( &retRect, -retRect.left, -retRect.top );
  321.     return( retRect );
  322. }
  323.  
  324. Rect TLayoutLeaf::GetRelativeRect()
  325. {
  326.     return( GetRect() );
  327. }
  328.  
  329. Rect TLayoutLeaf::GetRect()
  330. {
  331.     return( mContentRect );
  332. }
  333.  
  334. Boolean TLayoutLeaf::MakeActive( Boolean active )
  335. {
  336.     return( true );
  337. }
  338.  
  339. Boolean TLayoutBranch::MakeActive( Boolean active )
  340. {
  341.     if( mActiveChild )
  342.         return( mActiveChild->MakeActive( active ) );
  343.     else
  344.         return( false );
  345. }
  346.  
  347. Boolean TLayoutBranch::SetActiveChild( TLayoutLeaf *which )
  348. {
  349.     UInt32 childNum;
  350.     TChildStruct *child;
  351.  
  352.     if( (!which) && mActiveChild ) {
  353.         which= mActiveChild;
  354.         mActiveChild= 0l;
  355.         return( which->MakeActive( false ) );
  356.     }
  357.     if( !mChildren.MoveFirst() )
  358.         return( false );
  359.     do {
  360.         mChildren.GetData( child );
  361.     } while( mChildren.MoveNext() && (child->mChild != which ) );
  362.     if( child->mChild != which )
  363.         return( false );
  364.     if( mActiveChild && (mActiveChild != which) )
  365.         mActiveChild->MakeActive( false );
  366.     mActiveChild= which;
  367.     return( mActiveChild->MakeActive( true ) );
  368. }
  369.  
  370. void TLayoutLeaf::CalcMouseMove( Point pt, RgnHandle rgn )
  371. {
  372.     Rect localRect= GetRect();
  373.     RgnHandle myRgn= ::NewRgn();
  374.     if( mParent )
  375.         mParent->CalcClip( this, myRgn );
  376.     else
  377.         ::RectRgn( myRgn, &localRect );
  378.     if( ::PtInRgn( pt, myRgn ) ) {
  379.         ::CopyRgn( myRgn, rgn );
  380.         TMouseHandler::SGetMouse()->SetListener( this );
  381.     } else {
  382.         ::DiffRgn( rgn, myRgn, rgn );
  383.     }
  384.     ::DisposeRgn( myRgn );
  385. }
  386.  
  387. void TLayoutBranch::CalcMouseMove( Point pt, RgnHandle rgn )
  388. {
  389.     if( !mChildren.MoveFirst() ) {
  390.         TLayoutLeaf::CalcMouseMove( pt, rgn );
  391.         return;
  392.     }
  393.     UInt32 childInt;
  394.     TChildStruct *child;
  395.     Rect childRect;
  396.     do {
  397.         mChildren.GetData( child );
  398.         childRect= child->mChild->GetRect();
  399.         if( ::PtInRect( pt, &childRect ) ) {
  400.             child->mChild->CalcMouseMove( pt, rgn );
  401.             break;
  402.         }
  403.     } while( mChildren.MoveNext() );
  404.     if( !::PtInRect( pt, &childRect ) ) {
  405.         ::RectRgn( rgn, &mContentRect );
  406.         mChildren.MoveFirst();
  407.         RgnHandle rRgn= ::NewRgn();
  408.         do {
  409.             mChildren.GetData( child );
  410.             childRect= child->mChild->GetRect();
  411.             ::RectRgn( rRgn, &childRect );
  412.             ::DiffRgn( rgn, rRgn, rgn );
  413.         } while( mChildren.MoveNext() );
  414.         ::DisposeRgn( rRgn );
  415.     }
  416. }
  417.  
  418. void TLayoutLeaf::HandleMouseMoved( TMouseEvent *ev, bool within )
  419. {
  420.     if( within )
  421.         HandleMouseEnter();
  422.     else
  423.         HandleMouseExit();
  424. }
  425.  
  426. void TLayoutLeaf::GetClip( RgnHandle rgn )
  427. {
  428.     if( mParent )
  429.         mParent->CalcClip( this, rgn );
  430.     else
  431.         ::RectRgn( rgn, &mContentRect );
  432. }
  433.  
  434. void TLayoutBranch::CalcClip( TLayoutLeaf *child, RgnHandle rgn )
  435. {
  436.     TChildStruct *ch;
  437.     UINT32 temp;
  438.     bool found= false;
  439.     RgnHandle rRgn;
  440.  
  441.     if( !mChildren.MoveFirst() )
  442.         return;
  443.     if( mParent )
  444.         mParent->CalcClip( this, rgn );
  445.     else
  446.         ::RectRgn( rgn, &mContentRect );
  447.     rRgn= ::NewRgn();
  448.     do {
  449.         mChildren.GetData( ch );
  450.         found= (ch->mChild==child);
  451.         if( !found ) {
  452.             ::RectRgn( rRgn, &ch->mChild->GetRect() );
  453.             ::DiffRgn( rgn, rRgn, rgn );
  454.         }
  455.     } while( !found&&mChildren.MoveNext() );
  456.     if( found ) {
  457.         ::RectRgn( rRgn, &child->GetRect() );
  458.         ::SectRgn( rgn, rRgn, rgn );
  459.     }
  460.     ::DisposeRgn( rRgn );
  461. }
  462.  
  463. void TLayoutLeaf::HandleMouseEnter()
  464. {
  465.     ::SetCursor( &qd.arrow );
  466. }
  467.  
  468. void TLayoutLeaf::HandleMouseExit()
  469. {
  470. }